﻿#include "FileEncryption.h"
#include "ui_FileEncryption.h"

#include <QDebug>

FileEncryption::FileEncryption(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::FileEncryption)
{
    ui->setupUi(this);

    test_aes();

    test_aes_128();
}

FileEncryption::~FileEncryption()
{
    delete ui;
}

void FileEncryption::test_aes()
{
    auto key = Botan::hex_decode_locked("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
    auto block = Botan::hex_decode_locked("00112233445566778899AABBCCDDEEFF");
    const auto cipher = Botan::BlockCipher::create_or_throw("AES-256");
    cipher->set_key(key);
    cipher->encrypt(block);
    std::cout << cipher->name() << " single block encrypt: " << Botan::hex_encode(block) << '\n';

    // clear cipher for 2nd encryption with other key
    cipher->clear();
    key = Botan::hex_decode_locked("1337133713371337133713371337133713371337133713371337133713371337");
    cipher->set_key(key);
    cipher->encrypt(block);

    std::cout << cipher->name() << " single block encrypt: " << Botan::hex_encode(block) << '\n';
    return ;
}

void FileEncryption::test_aes_128()
{
    try {
        // 初始化随机数生成器
        Botan::AutoSeeded_RNG rng;

        // 1. 准备密钥 (Key) 和初始化向量 (IV)
        // 假设我们有一个口令，并通过 MD5 生成 128 位的密钥（注意：MD5 现在已不建议用于安全关键场景，此处仅作示例）
        std::string passphrase = "my_secret_password";
        auto hash = Botan::HashFunction::create("MD5");
        Botan::SymmetricKey key = hash->process(passphrase); // 产生128位的字节串作为密钥:cite[1]:cite[2]

        // 生成随机 IV (对于 CBC 模式等是必需的)
        Botan::InitializationVector iv(rng, 16); // 16 bytes for AES block size

        // 2. 明文数据
        std::string plaintext = "This is a secret message.";

        // 3. 加密
        // 创建加密器：指定算法、模式（如CBC）和操作类型
        std::unique_ptr<Botan::Cipher_Mode> encryptor = Botan::Cipher_Mode::create_or_throw("AES-128/CBC/PKCS7", Botan::ENCRYPTION);
        encryptor->set_key(key);
        encryptor->start(iv.bits_of()); // 设置 IV

        Botan::secure_vector<uint8_t> pt(plaintext.data(), plaintext.data() + plaintext.length());
        encryptor->finish(pt); // 执行加密

        std::cout << "Ciphertext: " << Botan::hex_encode(pt) << std::endl;
        std::cout << "IV: " << Botan::hex_encode(iv.bits_of()) << std::endl;

        // 4. 解密
        // 假设我们收到了密文和 IV
        Botan::secure_vector<uint8_t> ciphertext = pt; // 加密后的数据
        Botan::InitializationVector received_iv(iv.bits_of()); // 接收到的 IV

        std::unique_ptr<Botan::Cipher_Mode> decryptor = Botan::Cipher_Mode::create_or_throw("AES-128/CBC/PKCS7", Botan::DECRYPTION);
        decryptor->set_key(key);
        decryptor->start(received_iv.bits_of()); // 设置解密时使用的 IV

        decryptor->finish(ciphertext); // 执行解密

        std::string decrypted_text(ciphertext.begin(), ciphertext.end());
        std::cout << "Decrypted text: " << decrypted_text << std::endl;

    } catch (const Botan::Exception& e) {
        std::cerr << "Botan error: " << e.what() << std::endl;
        return ;
    } catch (const std::exception& e) {
        std::cerr << "Standard error: " << e.what() << std::endl;
        return ;
    }

    return ;
}

void FileEncryption::test_abs_cbc()
{

}

